[調査報告] Amazon Athena Icebergテーブルスキーマの変更を検証してみました!
AWS事業本部コンサルティング部の石川です。Amazon AthenaのIcebergテーブルスキーマ変更機能の挙動についてデータファイルのレベルで、実際に動作確認を行いましたので、その結果をご報告いたします。
Icebergテーブルのスキーマの進化(Schema Evolution)
Amazon AthenaのIcebergテーブルは、一般的なDBのようにテーブルのカラムの追加、変更、削除が可能です。その柔軟さからApache Icebergでは、スキーマ進化(Schema Evolution) と呼び、単純なカラムの変更、追加、削除以上の優れた機能を提供します。カラムの追加、変更、削除すると、その変更を適用するタイミングはいつで、大きなテーブルを対象にしたときにどのような影響が生じるのかなど、実際の運用面では挙動を把握する必要があります。
そこで、今回は、Icebergテーブルスキーマの進化を参考に、以下の操作について検証しました。
- カラムの追加(ALTER TABLE ADD COLUMNS)
- カラムの削除(ALTER TABLE DROP COLUMN)
- カラムの変更(ALTER TABLE CHANGE COLUMN)
それでは、各操作の結果を見ていきましょう。
ALTER TABLE ADD COLUMNS
既存のテーブルに新しいカラムを追加する操作を行いました。
ALTER TABLE ssbgzdb_tsv.customer_sevo ADD COLUMNS (col_bottom string);
検証用テーブル
下記のように検証用テーブルcustomer_sevo
を作成して、そのテーブルに初期データを投入しています。
-- DROP TABLE ssbgzdb_tsv.customer_sevo;
CREATE TABLE ssbgzdb_tsv.customer_sevo (
c_custkey int,
c_name string,
c_address string,
c_city string,
c_nation string,
c_region string,
c_phone string,
c_mktsegment string)
LOCATION 's3://cm-test-20241020/ssbgz_tsv/customer_sevo'
TBLPROPERTIES (
'table_type'='iceberg'
);
INSERT INTO ssbgzdb_tsv.customer_sevo
SELECT * FROM ssbgzdb_tsv.customer_ib;
SELECT COUNT(*) FROM ssbgzdb_tsv.customer_ib;
-- 3000000
上記のテーブルの全てファイル数を合計したデータサイズは、96736607バイトです。
% aws s3 ls s3://cm-test-20241020/ssbgz_tsv/customer_sevo --recursive --sum
2024-10-20 22:57:59 93659497 ssbgz_tsv/customer_sevo/data/6oU-WQ/20240306_135749_00126_z6eb5-975cb51e-4bd7-4b8e-8805-1adb53252f65.parquet
2024-10-20 18:00:46 3060966 ssbgz_tsv/customer_sevo/data/P0iKaQ/20240306_090017_00032_4xju6-8075927f-b65f-4818-aa0e-fd2e1e858e67.parquet
2024-10-20 22:57:12 1717 ssbgz_tsv/customer_sevo/metadata/00000-d7214be4-dcb6-4d01-99ea-32e05bf99009.metadata.json
2024-10-20 22:58:01 2860 ssbgz_tsv/customer_sevo/metadata/00001-ce217406-e9a3-4ada-8598-8a3b641b256d.metadata.json
2024-10-20 22:58:01 7291 ssbgz_tsv/customer_sevo/metadata/e0b3cc79-d8dc-4ea0-b959-be1f9acd53fc-m0.avro
2024-10-20 22:58:01 4276 ssbgz_tsv/customer_sevo/metadata/snap-4837344339604003165-1-e0b3cc79-d8dc-4ea0-b959-be1f9acd53fc.avro
Total Objects: 6
Total Size: 96736607
カラム追加
検証用のテーブルcustomer_sevo
にcol_bottom
カラムを追加しました。
ALTER TABLE ssbgzdb_tsv.customer_sevo ADD COLUMNS (col_bottom string);
SELECT COUNT(*) FROM ssbgzdb_tsv.customer_sevo WHERE col_bottom IS NULL;
-- 3000000
SELECT COUNT(*) FROM ssbgzdb_tsv.customer_sevo WHERE col_bottom = '';
-- 0
SHOW CREATE TABLE customer_sevo;
--- col_bottomカラムが追加されたことを確認
CREATE TABLE ssbgzdb_tsv.customer_sevo (
c_custkey int,
c_name string,
c_address string,
c_city string,
c_nation string,
c_region string,
c_phone string,
c_mktsegment string,
col_bottom string)
LOCATION 's3://cm-test-20241020/ssbgz_tsv/customer_sevo'
TBLPROPERTIES (
'table_type'='iceberg'
);
待たされることなく直ぐにカラムが追加されました。追加されたカラムには初期値としてNULL
が設定されることが確認できました。上記のテーブルのデータサイズは、96740613バイト(4006バイトの増加)、つまりほとんど増えていません。
% aws s3 ls s3://cm-test-20241020/ssbgz_tsv/customer_sevo --recursive --sum
2024-10-20 22:57:59 93659497 ssbgz_tsv/customer_sevo/data/6oU-WQ/20240306_135749_00126_z6eb5-975cb51e-4bd7-4b8e-8805-1adb53252f65.parquet
2024-10-20 18:00:46 3060966 ssbgz_tsv/customer_sevo/data/P0iKaQ/20240306_090017_00032_4xju6-8075927f-b65f-4818-aa0e-fd2e1e858e67.parquet
2024-10-20 22:57:12 1717 ssbgz_tsv/customer_sevo/metadata/00000-d7214be4-dcb6-4d01-99ea-32e05bf99009.metadata.json
2024-10-20 22:58:01 2860 ssbgz_tsv/customer_sevo/metadata/00001-ce217406-e9a3-4ada-8598-8a3b641b256d.metadata.json
2024-10-20 22:58:56 4006 ssbgz_tsv/customer_sevo/metadata/00002-3d4a2c2a-24d9-42e3-bab7-0cb13d336d87.metadata.json
2024-10-20 22:58:01 7291 ssbgz_tsv/customer_sevo/metadata/e0b3cc79-d8dc-4ea0-b959-be1f9acd53fc-m0.avro
2024-10-20 22:58:01 4276 ssbgz_tsv/customer_sevo/metadata/snap-4837344339604003165-1-e0b3cc79-d8dc-4ea0-b959-be1f9acd53fc.avro
Total Objects: 7
Total Size: 96740613
追加したカラムにデータを更新
追加したカラムにUPDATE文でデータを更新します。
UPDATE ssbgzdb_tsv.customer_sevo SET col_bottom = 'x';
データの更新には時間がかかりました。
% aws s3 ls s3://cm-test-20241020/ssbgz_tsv/customer_sevo --recursive --sum
2024-10-20 22:57:59 93659497 ssbgz_tsv/customer_sevo/data/6oU-WQ/20240306_135749_00126_z6eb5-975cb51e-4bd7-4b8e-8805-1adb53252f65.parquet
2024-10-20 18:00:46 3060966 ssbgz_tsv/customer_sevo/data/P0iKaQ/20240306_090017_00032_4xju6-8075927f-b65f-4818-aa0e-fd2e1e858e67.parquet
2024-10-20 23:02:06 3060966 ssbgz_tsv/customer_sevo/data/XTiF_Q/20240306_140145_00017_xhcgz-19c21c6a-1fa4-4ab5-85d5-319be0975204.parquet
2024-10-20 23:02:03 93662854 ssbgz_tsv/customer_sevo/data/z-rk1A/20240306_140145_00017_xhcgz-e9f93242-3c3f-4776-8129-6e34ca18b7a6.parquet
2024-10-20 22:57:12 1717 ssbgz_tsv/customer_sevo/metadata/00000-d7214be4-dcb6-4d01-99ea-32e05bf99009.metadata.json
2024-10-20 22:58:01 2860 ssbgz_tsv/customer_sevo/metadata/00001-ce217406-e9a3-4ada-8598-8a3b641b256d.metadata.json
2024-10-20 22:58:56 4006 ssbgz_tsv/customer_sevo/metadata/00002-3d4a2c2a-24d9-42e3-bab7-0cb13d336d87.metadata.json
2024-10-20 23:02:07 5901 ssbgz_tsv/customer_sevo/metadata/00003-b372d1d8-497f-4e67-a4ed-96be08e14162.metadata.json
2024-10-20 23:02:06 7356 ssbgz_tsv/customer_sevo/metadata/49f5a78f-f0ce-4880-afe9-68c0bf31c651-m0.avro
2024-10-20 23:02:06 7366 ssbgz_tsv/customer_sevo/metadata/6df1b724-3336-45b8-85d1-5bdfa71e2bd8-m0.avro
2024-10-20 22:58:01 7291 ssbgz_tsv/customer_sevo/metadata/e0b3cc79-d8dc-4ea0-b959-be1f9acd53fc-m0.avro
2024-10-20 22:58:01 4276 ssbgz_tsv/customer_sevo/metadata/snap-4837344339604003165-1-e0b3cc79-d8dc-4ea0-b959-be1f9acd53fc.avro
2024-10-20 23:02:06 4354 ssbgz_tsv/customer_sevo/metadata/snap-5312892158479628177-1-49f5a78f-f0ce-4880-afe9-68c0bf31c651.avro
2024-10-20 23:02:06 4348 ssbgz_tsv/customer_sevo/metadata/snap-778527561705377363-1-6df1b724-3336-45b8-85d1-5bdfa71e2bd8.avro
Total Objects: 14
Total Size: 193493758
上記のテーブルのデータサイズは、193493758バイト(96753145バイトの増加)、ほぼ倍に増えています。
恐らく、すべての行の更新に伴い、20240306_140145_00017_xxx.parquetファイルが2つ追加されたことが主な要因であり、既存のデータを更新したデータファイルが新たに作成されたと考えられます。
元のデータファイルが削除されるのは、履歴保持期間経過後にVACUUMを実行した際に開放されると考えられる。
結果
この操作の結果、以下のことが分かりました。
- カラムの追加自体はすぐに反映されます。
- データサイズはほとんど増加しません(今回の場合、4006バイトの増加)。
- 新しいカラムにデータを追加すると、データサイズが大幅に増加します(今回は約96MBの増加)。
これは、カラム追加時にはメタデータの変更のみが行われ、実際のデータファイルの更新はデータ追加時に行われるためです。今回は、プリミティブなString型のカラムを追加しましたが、構造体や配列なども追加可能です。
ALTER TABLE DROP COLUMN
次に、既存のカラムを削除する操作を行いました。
ALTER TABLE customer_sevo DROP COLUMN c_address;
検証用テーブル
下記のように検証用テーブルcustomer_sevo
を作成して、そのテーブルに初期データを投入しています。
-- DROP TABLE ssbgzdb_tsv.customer_sevo;
CREATE TABLE ssbgzdb_tsv.customer_sevo (
c_custkey int,
c_name string,
c_address string,
c_city string,
c_nation string,
c_region string,
c_phone string,
c_mktsegment string)
LOCATION 's3://cm-test-20241020/ssbgz_tsv/customer_sevo'
TBLPROPERTIES (
'table_type'='iceberg'
);
INSERT INTO ssbgzdb_tsv.customer_sevo
SELECT * FROM ssbgzdb_tsv.customer_ib;
SELECT COUNT(*) FROM ssbgzdb_tsv.customer_ib;
-- 3000000
上記のテーブルの全てファイル数を合計したデータサイズは、93681518バイトです。
% aws s3 ls s3://cm-test-20241020/ssbgz_tsv/customer_sevo --recursive --sum
2024-10-21 05:30:19 93665377 ssbgz_tsv/customer_sevo/data/WNQx5w/20240306_203008_00111_msics-e7b5c497-f469-4ac8-bb87-7d2a20006e5b.parquet
2024-10-21 05:30:02 1717 ssbgz_tsv/customer_sevo/metadata/00000-7035cb20-c76a-45a5-9b6a-3b46716a8646.metadata.json
2024-10-21 05:30:21 2860 ssbgz_tsv/customer_sevo/metadata/00001-264145f4-4e1e-453b-915a-e5ac61c778f6.metadata.json
2024-10-21 05:30:21 7291 ssbgz_tsv/customer_sevo/metadata/8d025d69-94b9-4af7-927f-0c3329bacbb2-m0.avro
2024-10-21 05:30:21 4273 ssbgz_tsv/customer_sevo/metadata/snap-4826230579802413408-1-8d025d69-94b9-4af7-927f-0c3329bacbb2.avro
Total Objects: 5
Total Size: 93681518
カラム削除
検証用のテーブルcustomer_sevo
にc_address
カラムを削除しました。
ALTER TABLE customer_sevo DROP COLUMN c_address;
SHOW CREATE TABLE customer_sevo;
--- c_addressカラムが削除されたことを確認
CREATE TABLE ssbgzdb_tsv.customer_sevo (
c_custkey int,
c_name string,
c_city string,
c_nation string,
c_region string,
c_phone string,
c_mktsegment string)
LOCATION 's3://cm-test-20241020/ssbgz_tsv/customer_sevo'
TBLPROPERTIES (
'table_type'='iceberg'
);
待たされることなく直ぐにカラムが削除されました。データサイズは、93685317バイト(3799バイトの増加)、つまり微妙に増えています。実際に削除されるのは、履歴保持期間経過後にVACUUMを実行した際に開放されると考えられます。
% aws s3 ls s3://cm-test-20241020/ssbgz_tsv/customer_sevo --recursive --sum
2024-10-21 05:30:19 93665377 ssbgz_tsv/customer_sevo/data/WNQx5w/20240306_203008_00111_msics-e7b5c497-f469-4ac8-bb87-7d2a20006e5b.parquet
2024-10-21 05:30:02 1717 ssbgz_tsv/customer_sevo/metadata/00000-7035cb20-c76a-45a5-9b6a-3b46716a8646.metadata.json
2024-10-21 05:30:21 2860 ssbgz_tsv/customer_sevo/metadata/00001-264145f4-4e1e-453b-915a-e5ac61c778f6.metadata.json
2024-10-21 05:52:31 3799 ssbgz_tsv/customer_sevo/metadata/00002-ee718a14-a75e-4efe-97b4-022c87818fba.metadata.json
2024-10-21 05:30:21 7291 ssbgz_tsv/customer_sevo/metadata/8d025d69-94b9-4af7-927f-0c3329bacbb2-m0.avro
2024-10-21 05:30:21 4273 ssbgz_tsv/customer_sevo/metadata/snap-4826230579802413408-1-8d025d69-94b9-4af7-927f-0c3329bacbb2.avro
Total Objects: 6
Total Size: 93685317
この操作の結果、以下のことが判明しました。
- カラムの削除はメタデータ上ですぐに反映されます。
- しかし、実際のデータサイズはわずかに増加します(今回は3799バイトの増加)。
- 実際のデータ削除は、履歴保持期間経過後にVACUUMを実行した際に行われると考えられます。
つまり、カラム削除操作は論理的な削除であり、物理的な削除はすぐには行われないということです。
ALTER TABLE CHANGE COLUMN
最後に、カラムの変更操作を検証しました。以下の3つの操作が可能であることを確認しました。
- カラム名の変更
- カラムの位置の変更
- データ型の変更(ただし、互換性のある型間のみ)
ALTER TABLE customer_sevo CHANGE col_bottom col_top string
ALTER TABLE customer_sevo CHANGE COLUMN col_top col_top string COMMENT 'test column' AFTER c_name;
ALTER TABLE customer_sevo CHANGE col_xxx col_xxx bigint
検証用テーブル
下記のように検証用テーブルcustomer_sevo
を作成して、そのテーブルに初期データを投入しています。
-- DROP TABLE ssbgzdb_tsv.customer_sevo;
CREATE TABLE ssbgzdb_tsv.customer_sevo (
c_custkey int,
c_name string,
c_address string,
c_city string,
c_nation string,
c_region string,
c_phone string,
c_mktsegment string)
LOCATION 's3://cm-test-20241020/ssbgz_tsv/customer_sevo'
TBLPROPERTIES (
'table_type'='iceberg'
);
INSERT INTO ssbgzdb_tsv.customer_sevo
SELECT * FROM ssbgzdb_tsv.customer_ib;
SELECT COUNT(*) FROM ssbgzdb_tsv.customer_ib;
-- 3000000
カラムの変更
col_bottom
をcol_top
にカラム名変更
ALTER TABLE customer_sevo CHANGE col_bottom col_top string
c_name
を後ろの位置に異動
ALTER TABLE customer_sevo CHANGE COLUMN col_top col_top string COMMENT 'test column' AFTER c_name;
col_xxx
をintからbigintにデータ型の変更- intからdoubleやstringへの変更はできません
ALTER TABLE customer_sevo ADD COLUMNS (col_xxx int);
ALTER TABLE customer_sevo CHANGE col_xxx col_xxx bigint
これらの操作は、データファイルの更新を伴わずに即時反映されることが分かりました。実際のデータの変更は、レコードが更新されるタイミングで行われるようです。
最後に
今回の検証を通じて、Amazon Athena のIcebergテーブルのスキーマ変更について、以下のことが明らかになりました。
- カラムの追加・削除・変更操作は、メタデータレベルですぐに反映されます。
- 実際のデータファイルの更新は、データの追加や更新時に行われます。
- カラムの削除では、物理的な削除はVACUUM実行時まで遅延されます。
- これらの特性により、スキーマ変更操作は高速で、大規模なデータ移動を伴わずに実行できます。
Amazon Athena Icebergテーブルのこれらの特性は、大規模なデータセットを扱う際に特に有用です。スキーマの進化を柔軟に行いながら、パフォーマンスへの影響を最小限に抑えることができます。
Athenaを使用している方々は、これらの機能を活用してデータモデルの進化をより効率的に管理できるでしょう。今後のプロジェクトでこの知見を活かしていただければ幸いです。